package com.ruoyi.system.controller;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.conf.MinioConfig;
import com.ruoyi.system.domain.PhotoRecord;
import com.ruoyi.system.domain.PhotoLate;
import com.ruoyi.system.service.IPhotoRecordService;
import com.ruoyi.system.service.IPhotoLateService;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Iterator;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/system/photo")
public class PhotoUploadController extends BaseController {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;
    
    @Autowired
    private IPhotoRecordService photoRecordService;

    @Autowired
    private IPhotoLateService photoLateService;

    // 定义最大图片尺寸
    private static final int MAX_WIDTH = 1920;
    private static final int MAX_HEIGHT = 1080;
    // 定义压缩质量
    private static final float COMPRESSION_QUALITY = 0.7f;

    /**
     * 压缩图片
     */
    private byte[] compressImage(MultipartFile file) throws Exception {
        // 读取原始图片
        BufferedImage originalImage = ImageIO.read(file.getInputStream());
        if (originalImage == null) {
            throw new Exception("无法读取图片");
        }

        // 计算新的尺寸
        int originalWidth = originalImage.getWidth();
        int originalHeight = originalImage.getHeight();
        int newWidth = originalWidth;
        int newHeight = originalHeight;

        // 如果图片尺寸超过最大值，等比例缩小
        if (originalWidth > MAX_WIDTH || originalHeight > MAX_HEIGHT) {
            double ratio = Math.min(
                (double) MAX_WIDTH / originalWidth,
                (double) MAX_HEIGHT / originalHeight
            );
            newWidth = (int) (originalWidth * ratio);
            newHeight = (int) (originalHeight * ratio);
        }

        // 创建新的图片
        BufferedImage resizedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = resizedImage.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(originalImage, 0, 0, newWidth, newHeight, null);
        g.dispose();

        // 压缩图片质量
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
        if (!writers.hasNext()) {
            throw new Exception("No image writer found for jpg format");
        }

        ImageWriter writer = writers.next();
        ImageOutputStream ios = ImageIO.createImageOutputStream(outputStream);
        writer.setOutput(ios);

        ImageWriteParam param = writer.getDefaultWriteParam();
        param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        param.setCompressionQuality(COMPRESSION_QUALITY);

        writer.write(null, new IIOImage(resizedImage, null, null), param);
        writer.dispose();
        ios.close();

        return outputStream.toByteArray();
    }

    /**
     * 上传图片
     */
    @PostMapping("/upload")
    public AjaxResult uploadPhoto(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return AjaxResult.error("上传文件不能为空");
            }

            // 压缩图片
            byte[] compressedImageData = compressImage(file);

            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileName = UUID.randomUUID().toString() + extension;

            // 上传到MinIO
            InputStream inputStream = new ByteArrayInputStream(compressedImageData);
            minioClient.putObject(
                PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, compressedImageData.length, -1)
                    .contentType(file.getContentType())
                    .build()
            );

            // 构建访问URL
            String url = minioConfig.getPublicUrl(fileName);

            return AjaxResult.success("上传成功", url);
        } catch (Exception e) {
            log.error("上传图片失败", e);
            return AjaxResult.error("上传图片失败：" + e.getMessage());
        }
    }

    /**
     * 提交反馈
     */
    @PostMapping("/feedback")
    public AjaxResult submitFeedback(@RequestBody PhotoRecord photoRecord) {
        try {
            // 保存反馈记录
            photoRecordService.insertPhotoRecord(photoRecord);
            return AjaxResult.success("反馈提交成功");
        } catch (Exception e) {
            log.error("提交反馈失败", e);
            return AjaxResult.error("提交反馈失败：" + e.getMessage());
        }
    }

    /**
     * 上传晚到拍照图片
     */
    @PostMapping("/uploadLatePhoto")
    public AjaxResult uploadLatePhoto(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return AjaxResult.error("上传文件不能为空");
            }

            // 压缩图片
            byte[] compressedImageData = compressImage(file);

            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileName = "late_" + UUID.randomUUID().toString() + extension;

            // 上传到MinIO
            InputStream inputStream = new ByteArrayInputStream(compressedImageData);
            minioClient.putObject(
                PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, compressedImageData.length, -1)
                    .contentType(file.getContentType())
                    .build()
            );

            // 构建访问URL
            String url = minioConfig.getPublicUrl(fileName);

            return AjaxResult.success("上传成功", url);
        } catch (Exception e) {
            log.error("上传晚到拍照图片失败", e);
            return AjaxResult.error("上传晚到拍照图片失败：" + e.getMessage());
        }
    }

    /**
     * 提交晚到拍照反馈
     */
    @PostMapping("/submitLateFeedback")
    public AjaxResult submitLateFeedback(@RequestBody PhotoLate photoLate) {
        try {
            // 保存晚到拍照记录
            photoLateService.insertPhotoLate(photoLate);
            return AjaxResult.success("晚到拍照记录提交成功");
        } catch (Exception e) {
            log.error("提交晚到拍照记录失败", e);
            return AjaxResult.error("提交晚到拍照记录失败：" + e.getMessage());
        }
    }

    /**
     * 上传班后报告照片
     */
    @PostMapping("/uploadBanhouPhoto")
    public AjaxResult uploadBanhouPhoto(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty()) {
                return AjaxResult.error("上传文件不能为空");
            }

            // 压缩图片
            byte[] compressedImageData = compressImage(file);

            // 生成文件名
            String originalFilename = file.getOriginalFilename();
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileName = "banhou_" + UUID.randomUUID().toString() + extension;

            // 上传到MinIO
            InputStream inputStream = new ByteArrayInputStream(compressedImageData);
            minioClient.putObject(
                PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(fileName)
                    .stream(inputStream, compressedImageData.length, -1)
                    .contentType(file.getContentType())
                    .build()
            );

            // 构建访问URL
            String url = minioConfig.getPublicUrl(fileName);

            return AjaxResult.success("上传成功", url);
        } catch (Exception e) {
            log.error("上传班后报告照片失败", e);
            return AjaxResult.error("上传班后报告照片失败：" + e.getMessage());
        }
    }
} 